package connect4swt.gui.connect4;

import game.Player;
import game.PlayerMove;
import game.connect4.Connect4Move;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.MessageBox;

import com.swtdesigner.SWTResourceManager;

import connect4swt.ClientApplication;
import connect4swt.gui.Board;
import connect4swt.gui.Piece;

public class Connect4Board extends Board{

	public Connect4Board(Canvas parentCanvas, Player me, Player opponent)
	{
		super(parentCanvas, me, opponent);
		
		this.parentCanvas.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				playPiece(null, new Point(e.x, e.y));
			}
		});
		
		this.parentCanvas.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent e) {
				//TODO: To implement a method which draws an arrow showing the piece drop zone
			}
		});		
		
		this.parentCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				paint();
				//just to test the information method
				drawGameInformationMessage("Connect4 game started!");
			}
		});
	}
	
	/**
	 * Initializes the board
	 *
	 */
	@Override
	protected void createPieces() {
		int pieceWidth = this.width / 7 - 1;
		int pieceHeight = this.height / 6;
		
		for(int y = 0; y < 6; y++) {
			for(int x = 0; x < 7; x++) {
				Piece piece = new Connect4Piece(Connect4Piece.ImageType.EMPTY,
						x * pieceWidth + 2,
						y * pieceHeight + 2 + this.yAxisOffset,
						pieceWidth,
						pieceHeight,
						new Point(x, y));
				this.pieces.add(piece);					
			}
		}
	}
	
	@Override
	protected void computeResize(){
			this.width = this.parentCanvas.getSize().x;
			this.height = Math.round(this.parentCanvas.getSize().y * 0.80f);
			this.yAxisOffset = this.parentCanvas.getSize().y - this.height;
			
			int pieceWidth = this.width / 7 - 1;
			int pieceHeight = this.height / 6;
	
			for(Piece piece : pieces) {
				piece.setX(piece.getPosition().x * pieceWidth + 2);
				piece.setY(piece.getPosition().y * pieceHeight + 2 + this.yAxisOffset);
				piece.setWidth(pieceWidth);
				piece.setHeight(pieceHeight);
			}
			
			this.gc = new GC(this.parentCanvas);
			//this.gc.setAntialias(SWT.OFF);
	}

	 
	//	If we have an agreement about this way of displaying game information, we'll have to
	//play with text size and its position, otherwise we'll display that information
	//in a label or textbox!
	@Override
	protected void drawGameInformationMessage(String message) {
		GC infoGC = new GC(this.parentCanvas);
		
		infoGC.setClipping(10, 3, this.width - 19, 66);
		//infoGC.setAntialias(SWT.OFF);
		
		infoGC.setBackground(SWTResourceManager.getColor(255, 255, 255));
		infoGC.setForeground(SWTResourceManager.getColor(255, 0, 0));
		infoGC.setFont(SWTResourceManager.getFont("Arial", 8, SWT.BOLD));
		infoGC.drawText(message, infoGC.getClipping().width - 130, 54);
		
		infoGC.dispose();
	}
	
	@Override
	protected void drawPlayersInformation() {
		
		GC rankGC = new GC(this.parentCanvas);
		
		rankGC.setClipping(10, 3, this.width - 19, 66);
		//rankGC.setAntialias(SWT.OFF);
		
		//Drawing the rectangle which holds game information
		rankGC.setLineWidth(1);
		rankGC.setForeground(SWTResourceManager.getColor(80, 80, 80));
		rankGC.drawRectangle(10, 3, this.width - 20, 65);
		rankGC.setBackground(SWTResourceManager.getColor(255, 255, 255));
		rankGC.fillRectangle(12, 5, this.width - 23, 63);
		
		//Drawing players' names
		rankGC.setForeground(SWTResourceManager.getColor(150, 150, 150));
		rankGC.setFont(SWTResourceManager.getFont("Arial", 14, SWT.BOLD));
		//rankGC.drawText(this.playerOne.getName() + ": " + this.playerOne.getRank(), 15, 8, true);
		rankGC.drawText(player1+":"+ ranking1, 15, 8, true);
		rankGC.setForeground(SWTResourceManager.getColor(150, 150, 150));
		//rankGC.drawText(this.playerOne.getName() + ": " + this.playerOne.getRank(), 15, 40, true);
		rankGC.drawText(player2+":"+ ranking2, 15, 40, true);
		
		rankGC.dispose();
	}
	
	@Override
	protected void drawGameBoard() {
		
		//Drawing the canvas border
		this.gc.setLineWidth(2);
		this.gc.setForeground(SWTResourceManager.getColor(0, 80, 180));
		this.gc.drawRectangle(1, this.yAxisOffset + 1, (this.width / 7 - 1) * 7 + 2, this.height - 2);
		
		for(Piece piece : this.pieces) {
			this.gc.drawImage(piece.getImage(),
					0,
					0,
					piece.getImage().getImageData().width,
					piece.getImage().getImageData().height,
					piece.getX(),
					piece.getY(),
					piece.getWidth(), 
					piece.getHeight());
		}
	}
	
	@Override
	protected void fillPiece(PlayerMove move){
		Connect4Move connect4Move = (Connect4Move)move;
		Piece pieceToPlay = getPieceFromBoardPosition(new Point(connect4Move.getColumn(), 0));
		if(this.playerOneTurn)
			((Connect4Piece)pieceToPlay).setType(Connect4Piece.ImageType.GREEN);
		else
			((Connect4Piece)pieceToPlay).setType(Connect4Piece.ImageType.RED);
				
		GC tempGC = new GC(this.parentCanvas);
		//tempGC.setAntialias(SWT.OFF);
		
		tempGC.setClipping(pieceToPlay.getX() , pieceToPlay.getY(), pieceToPlay.getX() + pieceToPlay.getWidth(), pieceToPlay.getY() + pieceToPlay.getHeight());
		tempGC.drawImage(pieceToPlay.getImage(),
				0,
				0,
				pieceToPlay.getImage().getImageData().width,
				pieceToPlay.getImage().getImageData().height,
				pieceToPlay.getX(),
				pieceToPlay.getY(),
				pieceToPlay.getWidth(), 
				pieceToPlay.getHeight());
		
		tempGC.dispose();
	}
		
	@Override
	public void playPiece(Point oldPosition, Point newPosition) {	
		
		Connect4Piece pieceToPlay = (Connect4Piece)getPieceFromMousePosition(newPosition);		
		
		
		if(pieceToPlay != null) 
			if(this.isMatchOver ){
				MessageBox msgBox = new MessageBox(this.parentCanvas.getShell(), SWT.ICON_INFORMATION | SWT.OK);
				msgBox.setText("Info");
				msgBox.setMessage("The match is already over!");	
				msgBox.open();
			}				
			else if(this.playerOneTurn){ 				
				ClientApplication.getController().getGUIMediator().sendPlayerMoveMessage(matchId, new Connect4Move(pieceToPlay.getBoardPositionX()));
				this.playerOneTurn = false;
			}
			else {				
				//	MessageBox msgBox = new MessageBox(this.parentCanvas.getShell(), SWT.ICON_QUESTION | SWT.OK);
				//	msgBox.setText("Invalid Move");
				//	msgBox.setMessage("It is not your turn to play!");	
				//	msgBox.open();
			}					
	}	

	@Override
	protected Piece getPieceFromMousePosition(Point position) {
		Connect4Piece tempPiece = null;
		
		for(Piece piece : pieces) {			
			if(position.x >= piece.getX() && position.x <= (piece.getX() + piece.getWidth()) && piece.isEmpty()) {
				tempPiece = (Connect4Piece)piece;
			}
		}
		return tempPiece;	
	}

	@Override
	protected Piece getPieceFromBoardPosition(Point position) {
	int length = this.pieces.size() - 1;
		
		for(int i = length; i >= 0;i--){
			 if(this.pieces.get(i).getBoardPositionX() == position.x && this.pieces.get(i).isEmpty())				
				return (Connect4Piece)this.pieces.get(i);						
		}
		return null;
	}

	@Override
	protected void drawPiece(Piece piece) {
		// TODO Auto-generated method stub
		
	}

}
